package uit.nfcmenu.activity;

import java.util.ArrayList;
import java.util.Collections;

import uit.nfcmenu.R;
import uit.nfcmenu.db.model.IDataChangeHandler;
import uit.nfcmenu.db.model.MenuModel;
import uit.nfcmenu.manager.AssetsManager;
import uit.nfcmenu.util.CommConstant;
import uit.nfcmenu.util.UiUtilities.ICallBack;
import uit.nfcmenu.view.MenuAdapter;
import uit.nfcmenu.webservice.MyException;
import uit.nfcmenu.webservice.WSMapping;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;

public class WaiterMenuActivity extends BaseActivity implements
		IDataChangeHandler, OnClickListener, ICallBack {
	public static String tag = WaiterMenuActivity.class.getSimpleName();
	

//	private Button btnRefresh;

	private LinearLayout gestureLayout;
	private ListView mMenuGrid;
	private MenuAdapter adapter;
	
	private ArrayList<MenuModel> mModels;

	boolean isSavedImgs = false;
	boolean isAccessible;
	boolean isRunOnFirstTime;

	long time;

	float x;
	float y;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_menu);

		initView();
		initData();
		initListener();
		
		isRunOnFirstTime = true;
	}
	
	@Override
	protected Context getActivityContext() {
		return this;
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (isRunOnFirstTime) {
			isRunOnFirstTime = false;
			setProgressBarShowable(true);
			startLoadingData(SHOW_MESSAGE_ON_DIALOG);
		}
		if (isDataChangedOnView) {
			Log.e(tag, "isDataChangedOnView=true, reload and view MENUS from db");
			isDataChangedOnView = false;
			setProgressBarShowable(true);
			mModels = getMenus();
			updateInView(mModels);
		}
		setProgressBarShowable(false);
	}

	private void startLoadingData(int status) {
		boolean result = doIfMeetNetworkOrShowFailStatus(mContext, status, 
				new Runnable() { @Override public void run() {
					new MenusLoader().execute();
				}});
		// if data can not loaded
		if (!result) {
			// load and view from db
			Log.e(tag, "offline, load and view MENUS from db");
			mModels = getMenus();
			updateInView(mModels);
		}
	}
	
	@Override
	public void notifyDataChanged() {
		Log.i(tag, "notifyDataChanged() " 
				+"WSMapping.isMenusChanged="+WSMapping.isMenusChanged
				+"isDataChangedOnView="+isDataChangedOnView);
		if (WSMapping.isMenusChanged) {
			WSMapping.isMenusChanged = false;
			doIfMeetNetworkOrShowFailStatus(mContext, SHOW_NOTHING,
					new Runnable() { @Override public void run() {
						new RunLoader(new MenusLoader()).run();	
			}});
		}
	}

	protected void changeLanguage(String language) { }

	@Override
	protected void initView() {
		super.initView();
		AssetsManager.setCommonAppFont(this, R.id.tv_title);

//		btnRefresh = (Button) findViewById(R.id.btnRefresh);
		mMenuGrid = (ListView) findViewById(R.id.list);
		/*
		 * ttnlan: this gesture is layout above all view in menu screen but not
		 * complete, here we use background to accept listener instead the
		 * gesture to avoid more bugs
		 */
		gestureLayout = (LinearLayout) findViewById(R.id.main_layout);
	}

	protected void initData() {
		String[] statuses = mRes.getStringArray(R.array.status_array);
		String[] languages = mRes.getStringArray(R.array.arr_languages);
		CommConstant.initData(statuses, languages);
	}

	@Override
	protected void updateInView(Object... o) {
		ArrayList<MenuModel> models = (ArrayList<MenuModel>) o[0];
		Log.w(tag, "updateList():"+models.size());
		
		Collections.reverse(models); // to consistent order of server
		if (adapter == null) {
			adapter = new MenuAdapter(mContext, models,
					WaiterMenuActivity.this);
			mMenuGrid.setAdapter(adapter);
		} else {
			adapter.setmModels(models);
			adapter.notifyDataSetChanged();
		}
	}

	protected void initListener() {
//		btnRefresh.setOnClickListener(this);

		mMenuGrid.setOnItemClickListener(onMenuItem_click());
		
		gestureLayout.setOnTouchListener(createListener_gesture_touch());
	}

	private OnItemClickListener onMenuItem_click() {
		return new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1,
					int position, long arg3) {
				// Log.e(tag, "click="+position);
				launchItemActivity(position);
			}
		};
	}

	// ttnlan: fade-out for the finish()
//	private void launchLoginActivity() {
//		finish();
//		this.onBackPressed();
//	}

	private void launchItemActivity(int index) {
		int mainId = mModels.get(index).getId();
		String mainName = mModels.get(index).getName();
		Intent intent = new Intent(this, WaiterItemActivity.class);
		Bundle b = new Bundle();
		b.putInt("position", index);
		b.putInt("mainId", mainId);
		b.putString("mainName", mainName);
		intent.putExtras(b);
		startActivity(intent);
	}
	
	@Override
	public void callBack(int id) {
		launchItemActivity(id);
	}

	public void onClick(View v) {
		// Log.i(tag, "onTouch()");
//		switch (v.getId()) {
//		case R.id.btnRefresh:
//			doIfMeetNetworkOrShowFailStatus(mContext, SHOW_MESSAGE_ON_TOAST,
//					new Runnable() { @Override public void run() {
//						new MenusLoader().execute();
//			}});
//			break;
//		}
	}
	
	private class MenusLoader extends BaseLoader {
		@Override
		protected Integer doInBackground(Void... params) {
			// get data from db. If empty, request data from server
			mModels = getMenus();
			if (mModels == null || mModels.size() == 0) {
				try {
					updateMenusFromServer();
				} catch (MyException e) {
					Log.e(tag, "Loader catch MyException ", e);
				}
				mModels = getMenus();
			}
			return super.doInBackground(params);
		}
		
		@Override
		protected void onPostExecute(Integer result) {
			super.onPostExecute(result);
			updateInView(mModels);
		}
	}
	
	private OnTouchListener createListener_gesture_touch() {
		return new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					// Log.i(tag, "onTouch() DOWN x,y = " + x + "," + y);
					x = event.getX();
					y = event.getY();

					time = System.currentTimeMillis();
					isAccessible = true; // this
				}

				if (event.getAction() == MotionEvent.ACTION_MOVE) {
					// Log.i(tag, "onTouch() MOVE x,y = " + event.getX() + "," +
					// event.getY());

					isAccessible = true;
				}

				else if (event.getAction() == MotionEvent.ACTION_UP) {
					if (System.currentTimeMillis() - time < 200) {
						isAccessible = false; // sub
					} else {
						isAccessible = true; // this
					}

					Log.i(tag, "onTouch() UP x,y = " + event.getX() + ","
							+ event.getY());
					if (event.getX() < (x - 200)) {
						launchOrderListActivity();
						return true;
					}
					// left to right -> call LogInActivity
					else if (event.getX() > (x + 200)) {
						launchLoginActivity();
						return true;
					}
				}

				Log.i(tag, "isAccessible=" + isAccessible);
				return isAccessible;
			}
		};
	}

	public OnTouchListener createListener_gesture_touch1() {
		return new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {

				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					Log.i(tag, "onTouch() DOWN x,y = " + x + "," + y);
					x = event.getX();
					y = event.getY();
				}

				else if (event.getAction() == MotionEvent.ACTION_UP) {
					Log.i(tag, "onTouch() UP x,y = " + event.getX() + ","
							+ event.getY());
					if (event.getX() < (x - 200)) {
						launchOrderListActivity();
						return true;
					}
					else if (event.getX() > (x + 200)) {
						launchLoginActivity();
						return true;
					}
				}
				return true;
			}
		};
	}
}
